﻿using EmgrMvc.BLL;
using EmgrMvc.Models;
using Microsoft.EntityFrameworkCore;
using Quartz;
using Quartz.Impl;
using System;
using System.Collections.Generic;
using System.Linq;
using uPLibrary.Networking.M2Mqtt;
using uPLibrary.Networking.M2Mqtt.Messages;

namespace EmgrService
{
    class Program
    {
        static MyContext db;
        static IScheduler scheduler;
        static EsysBLL bll;

        static void Main(string[] args)
        {
            db = new MyContext(
                new DbContextOptionsBuilder<MyContext>()
                .UseSqlite("Filename=d:\\db\\app.db")
                .Options);

            bll = new EsysBLL(db);

            var schedulerFactory = new StdSchedulerFactory();
            scheduler = schedulerFactory.GetScheduler().Result;
            scheduler.Start();
            Console.WriteLine($"任务调度器已启动");

            MqttProc();
            ScheduleJobProc();

            Console.ReadKey();
        }

        static void MqttProc()
        {
            string brokerHostName = "gzhwedu.cn";
            int brokerPort = 1883;
            string clientId = "appnotify-" + Guid.NewGuid().ToString().Substring(0,8);
            //string username = "develop";
            //string password = "666666";
            string[] topic = { "status/#", "schedule/reset" };
            byte[] qosLevels = { MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE, MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE };
            //string caPath = "C:/MqttSSL/ca.crt";
            //X509Certificate caCert = new X509Certificate(caPath);
            //Console.WriteLine(caCert.ToString(true) + "\n" + caCert.ToString());
            //Console.ReadKey();
            Console.WriteLine("------------------------分割线-------------------------------");
            //无SSL连接
            try
            {
                MqttClient client = new MqttClient(brokerHostName, brokerPort, false, null, null, MqttSslProtocols.None);
                //单向SSL通信
                //MqttClient client = new MqttClient(brokerHostName, brokerPort, true, caCert, null, MqttSslProtocols.TLSv1_2, new RemoteCertificateValidationCallback(cafileValidCallback));
                //消息接受
                client.MqttMsgPublishReceived += new MqttClient.MqttMsgPublishEventHandler(messageReceive);
                //连接Broker
                client.Connect(clientId);
                Console.WriteLine("连接成功!");
                //client.Connect(clientId, username, password);

                client.Subscribe(topic, qosLevels);
            }
            catch (System.Exception)
            {
                Console.WriteLine("连接失败!");
            }
        }

        static void messageReceive(object sender, MqttMsgPublishEventArgs e)
        {
            string msg = "Topic:" + e.Topic + "   Message:" + System.Text.Encoding.Default.GetString(e.Message);
            Console.Write(DateTime.Now);
            Console.Write(": ");
            Console.WriteLine(msg);

            string deviceTopic = System.Text.Encoding.Default.GetString(e.Message);

            try
            {
                if (e.Topic == "status/on")
                {
                    bll.UpdateDeviceStatus(deviceTopic, "ON");
                }
                else if (e.Topic == "status/off")
                {
                    bll.UpdateDeviceStatus(deviceTopic, "OFF");
                }
                else if (e.Topic == "schedule/reset")
                {
                    //bll.InitOntimeJob();
                    ScheduleJobProc();
                }
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

        }

        static void ScheduleJobProc()
        {

            EsysBLL bll = new EsysBLL(db);
            bll.InitOntimeJob(scheduler);

            //foreach (var job in db.scheduleJobs.Where(x => x.active).ToList())
            //{
            //    JobData data = db.jobDatas.Find(job.jobDataId);
            //    Trigger trigger = db.Triggers.Find(job.triggerId);

            //    //备注：cron表达式的格式是：秒 时 分 日 月 星期。其中，日和星期不能同时指定，需要有一个使用“?”表示不确定的值。
            //    string cron = string.Format("{0} {1} {2} ? * {3}", trigger.Second, trigger.Minute, trigger.Hour, trigger.WeekDay);

            //    var jobDetail = JobBuilder.Create<AppJob>()
            //        .WithIdentity("id1", "group1")
            //        .SetJobData(new JobDataMap() {
            //                    new KeyValuePair<string, object>("GroupId", data.groupId),
            //                    new KeyValuePair<string, object>("Action", data.Action),
            //                    new KeyValuePair<string, object>("Db", db)
            //                    }).Build();

            //    Console.WriteLine(cron);

            //    var JobTrigger = TriggerBuilder.Create()
            //                                .WithCronSchedule("0/5 * * * * ?")
            //                                //.WithSimpleSchedule(m => m.WithRepeatCount(3).WithIntervalInMinutes(1))
            //                                //.StartAt(DateTime.Now + TimeSpan.FromSeconds(30))
            //                                .Build();

            //    //var JobTrigger = TriggerBuilder.Create()
            //    //                            //.WithSimpleSchedule(m =>
            //    //                            //{
            //    //                            //    m.WithRepeatCount(3).WithIntervalInSeconds(1);
            //    //                            //})
            //    //                            .WithCronSchedule("0/5 23 * ? * *")
            //    //                            .Build();

            //    //添加调度
            //    scheduler.ScheduleJob(jobDetail, JobTrigger);
            //}
            //ScheduleTool.Init();
            //ScheduleTool.TestTask();
        }

    }
}
